//
//  PlSInjector_RemovingFromLaunchd.m
//  Injector
//
//  Created by ∞ on 17/12/07.
//  Copyright 2007 Emanuele Vulcano (infinite-labs.net). All rights reserved.
//

#import "PlSInjector_RemovingFromLaunchd.h"

#define kPlSAgentIdentifier @"net.infinite-labs.PlugSuit.Agent"
#define kPlSPlugSuitErrorDomain @"kPlSPlugSuitErrorDomain"

enum {
	kPlSPlugSuitErrorLaunchctl,
};

@implementation PlSInjector (RemovingFromLaunchd)

// copied and adapted from PlugSuitPref.m -- FIXME needs proper refactoring.

- (NSError*) launchctlError {
	return [NSError errorWithDomain:kPlSPlugSuitErrorDomain code:kPlSPlugSuitErrorLaunchctl userInfo:
			[NSDictionary dictionaryWithObjectsAndKeys:
			 NSLocalizedString(@"Mac OS X returned an error when trying to modify PlugSuit's status.", @"Launchctl error description"), NSLocalizedDescriptionKey,
			 NSLocalizedString(@"The system refused to start or stop PlugSuit as a system service for some reason, but didn't tell why. You could try again, or contact support at plugsuit@infinite-labs.net.",  @"Launchctl error reason"), NSLocalizedFailureReasonErrorKey,
			 nil]
			];
}

- (NSString*) agentsDirectoryWithError:(NSError**) error {
	NSArray* ar = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
	if ([ar count] == 0) {
		if (error) *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:ENOENT userInfo:nil];
		return nil;
	}
	
	NSString* dir = [[ar objectAtIndex:0] stringByAppendingPathComponent:@"LaunchAgents"];
	NSFileManager* fm = [NSFileManager defaultManager];
	if (![fm fileExistsAtPath:dir] && ![fm createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:error])
		return nil;
	
	return dir;
}

- (BOOL) disableWithError:(NSError**) error {
	NSString* agentsDir = [self agentsDirectoryWithError:error];
	if (!agentsDir) return NO;
	
	NSString* plistName = [kPlSAgentIdentifier stringByAppendingPathExtension:@"plist"];
	plistName = [agentsDir stringByAppendingPathComponent:plistName];
	
	NSFileManager* fm = [NSFileManager defaultManager];
	
	if ([fm fileExistsAtPath:plistName]) {
		NSTask* task = [NSTask new];
		[task setLaunchPath:@"/bin/launchctl"];
		[task setArguments:[NSArray arrayWithObjects:@"unload", @"-wF", @"-S", @"Aqua", plistName, nil]];
		[task launch];
		[task waitUntilExit];
		
		if ([task terminationStatus] != 0) {
			if (error) *error = [self launchctlError];
			return NO;
		}
		
		if (![fm removeItemAtPath:plistName error:error])
			return NO;
	}
	
	return YES;
}

- (void) disableWithUserInteraction {
	NSError* err = nil;
	if (![self disableWithError:&err]) {
		[NSApp activateIgnoringOtherApps:YES];
		if ([NSApp presentError:err])
			[self disableWithUserInteraction];
	}
}

@end
